<script setup lang='ts'>
import { ref, CSSProperties, reactive, Directive} from 'vue'
import {headerProps, headerEmits, SearchFromJustify, OperButton} from './dHeader'
import {FormRules} from 'element-plus'
import type {ElForm} from 'element-plus'
import dIcon from '../dIcon.vue'

import zhCN from 'ant-design-vue/es/locale/zh_CN'
import { IconConfig } from '@/api/config'
const props = defineProps(headerProps)

const emits = defineEmits(headerEmits)
const getButtonShow = (oper:OperButton) => {
  return true
}

const getButtonLabel = (oper:OperButton) => {
  return oper.label
}
const inputsearchWidth = ref(468)
const getInputsearchStyle = (width:number|undefined) => {
  const style:CSSProperties = {}
  style.width = width ? width + 'px' : inputsearchWidth.value + 'px'
  return style
}

//表单居左还是居右
const flexEnd = (justify:SearchFromJustify) => {
  if (justify === 'flexEnd') {
    return 'd-comon-flex-justend'
  }
  return undefined
}
//表单部分自动填充
const flexFull = (full:boolean) => {
  if (full) {
    return 'd-common-flex-full'
  }
  return undefined
}

type FormInstance=InstanceType<typeof ElForm>
const formRef = ref<FormInstance>()

const clearEmpty = () => {
  const formData = props.searchFormData
  for (const key in formData) {
    const data = formData[key]
    if (data === '') formData[key] = undefined
  }
}
//提交搜索表单
const onSubmit = (inputSearchValue?:string|null) => {
  if (inputSearchValue && inputSearchValue.length > 50) {
    return false
  }
  const elForm = formRef.value
  if (!elForm) return
  elForm.validate((valid) => {
    if (valid) {
      if (props.clearEmpty) {
        clearEmpty()
      }
      emits('formSubmit')
    }
    else {
      return false
    }
  })
}

//清楚搜索表单
const onClear = () => {
  const elForm = formRef.value
  if (!elForm) return
  const resetProps:Array<string> = []
  props.searchFormItems.forEach((item) => {
    if (!item.notClearable) resetProps.push(item.prop)
  })
  elForm.resetFields(resetProps)
  emits('formClear')
}

//操作
const onOperation = (name:string) => {
  emits('operation', name)
}

const inputSearchRule = reactive<FormRules>({
  value:[
    {required:false, message:'长度应不超过50个字符', trigger:['change', 'blur'], max:50}
  ]
})

//elinput聚焦
const onElFocus = (el:HTMLDivElement) => {
  //el的input在三层
  if (el.children[0] && el.children[0].children[0]) {
    const input = el.children[0].children[0] as HTMLInputElement
    input.focus()
  }
}

//elinput聚焦
const vElFocus:Directive<HTMLDivElement, boolean|undefined> = {
  mounted(el, focus) {
    if (focus.value) {
      onElFocus(el)
    }
  }
}

//配置
const searchIcon:IconConfig = {icon:'Search', type:'el', size:16}
const clearIcon:IconConfig = {icon:'Refresh', type:'el', size:16}
</script>

<template>
  <div id="dHeader" ref="dHeader" class="d-common-flex-row d-table-header__wapper d-common-flex-waper">
    <div v-if="relativePosition==='lr'" class="d-common-flex-row d-common-flex-waper">
      <slot name="operbutton-prepend" />
      <template v-for="operbutton in operButtons" :key="operbutton.code">
        <template v-if="getButtonShow(operbutton)">
          <el-button
            v-if="operbutton.type==='noraml'||operbutton.type==='icon'"
            v-blur
            :type="operbutton.elType?operbutton.elType:'primary'"
            :plain="operbutton.plain"
            :style="operbutton.style"
            :class="operbutton.class"
            :loading="showLoading"
            @click="onOperation(operbutton.code)"
          >
            <d-icon v-if="operbutton.iconConfig" class="el-icon el-icon--left" :icon-config="operbutton.iconConfig" />
            {{ operbutton.type==='icon'?'':getButtonLabel(operbutton) }}
          </el-button>
          <el-button
            v-else-if="operbutton.type==='link'"
            v-blur
            type="primary"
            link
            :style="operbutton.style"
            :class="operbutton.class"
            :loading="showLoading"
            @click="onOperation(operbutton.code)"
          >
            {{ getButtonLabel(operbutton) }}
          </el-button>
        </template>
      </template>
      <slot name="operbutton-append" />
    </div>
    <el-form
      ref="formRef"
      class="d-table-form d-table-from-con d-common-flex-row d-common-flex-waper"
      :class="[flexEnd(searchFromJustify),flexFull(searchFromFull)]"
      :rules="searchRules"
      :model="searchFormData"
      label-position="right"
      :label-width="labelWidth"
      @submit.prevent
    >
      <el-form-item v-for="searchitem in searchFormItems" :key="searchitem.prop" :label="searchitem.label" :prop="searchitem.prop" :class="searchitem.class" :style="searchitem.style">
        <el-input
          v-if="searchitem.type==='input'"
          v-model="searchFormData[searchitem.prop]"
          v-el-focus="searchitem.autofocus"
          :clearable="!searchitem.notClearable"
          :placeholder="searchitem.placeholder"
          :maxlength="searchitem.maxlength"
          :disabled="searchitem.disabled"
          @keyup.enter="searchitem.enterSubmit?onSubmit():null"
        >
          <template #suffix>
            <span :class="searchitem.suffixIcon">
              {{ searchitem.suffixText }}
            </span>
          </template>
        </el-input>
        <el-input-number
          v-else-if="searchitem.type==='inputNumber'"
          v-model="searchFormData[searchitem.prop]"
          v-el-focus="searchitem.autofocus"
          controls-position="right"
          class="d-input-text-left"
          :max="searchitem.max"
          :min="searchitem.min"
          :step-strictly="!searchitem.notStrictly"
          :clearable="!searchitem.notClearable"
          :step="searchitem.step"
          :placeholder="searchitem.placeholder"
          @keyup.enter="searchitem.enterSubmit?onSubmit():null"
        />
        <el-select
          v-else-if="searchitem.type==='selete'"
          v-model="searchFormData[searchitem.prop]"
          :clearable="!searchitem.notClearable"
          :multiple="searchitem.multiple"
          :collapse-tags="searchitem.multiple"
          :filterable="searchitem.filterable"
          :placeholder="searchitem.placeholder"
          :remote="searchitem.remoteConfig&&searchitem.remoteConfig.remote"
          :remote-method="searchitem.remoteConfig&&searchitem.remoteConfig.remoteMethod?searchitem.remoteConfig.remoteMethod:undefined"
          :loading="searchitem.remoteConfig&&searchitem.remoteConfig.loading"
          @change="searchitem.changeSubmit?onSubmit():null"
        >
          <el-option v-for="item in searchitem.seleteData" :key="''+item.value" :label="item.label" :value="item.value" />
        </el-select>
        <el-select-v2
          v-else-if="searchitem.type==='seleteV2'"
          v-model="searchFormData[searchitem.prop]"
          :options="searchitem.seleteData"
          :clearable="!searchitem.notClearable"
          :multiple="searchitem.multiple"
          :collapse-tags="searchitem.multiple"
          :filterable="searchitem.filterable"
          :placeholder="searchitem.placeholder"
          :remote="searchitem.remoteConfig&&searchitem.remoteConfig.remote"
          :remote-method="searchitem.remoteConfig&&searchitem.remoteConfig.remoteMethod?searchitem.remoteConfig.remoteMethod:undefined"
          :loading="searchitem.remoteConfig&&searchitem.remoteConfig.loading"
          @change="searchitem.changeSubmit?onSubmit():null"
        />
        <el-tree-select
          v-else-if="searchitem.type==='seleteTree'"
          v-model="searchFormData[searchitem.prop]"
          :data="searchitem.seleteData"
          :clearable="!searchitem.notClearable"
          :multiple="searchitem.multiple"
          :collapse-tags="searchitem.multiple"
          :show-checkbox="searchitem.showCheckbox"
          :check-strictly="searchitem.checkStrictly"
          :placeholder="searchitem.placeholder"
          @change="searchitem.changeSubmit?onSubmit():null"
        />
        <el-radio-group v-else-if="searchitem.type==='radio'" v-model="searchFormData[searchitem.prop]">
          <el-radio v-for="data in searchitem.seleteData" :key="''+data.value" :label="data.value">
            {{ data.label }}
          </el-radio>
        </el-radio-group>
        <a-config-provider v-else-if="searchitem.type==='antdDate'" :locale="zhCN">
          <A-date-picker
            v-model:value="searchFormData[searchitem.prop]"
            :placeholder="searchitem.placeholder"
            :allow-clear="!searchitem.notClearable"
            :clearable="!searchitem.notClearable"
            :format="searchitem.dateFormat"
            :value-format="searchitem.dateFormat"
            :show-time="searchitem.showTime"
            :disabled-date="searchitem.disabledDate"
            @open-change="searchitem.openChange"
            @calendar-change="searchitem.calendarChange"
            @ok="searchitem.changeSubmit?onSubmit():null"
            @change="searchitem.changeSubmit?onSubmit():null"
          />
        </a-config-provider>
        <a-config-provider v-else-if="searchitem.type==='antdRange'" :locale="zhCN">
          <A-range-picker
            v-model:value="searchFormData[searchitem.prop]"
            :placeholder="searchitem.placeholder"
            :allow-clear="!searchitem.notClearable"
            :clearable="!searchitem.notClearable"
            :format="searchitem.dateFormat"
            :value-format="searchitem.dateFormat"
            :show-time="searchitem.showTime"
            :disabled-date="searchitem.disabledDate"
            @open-change="searchitem.openChange"
            @calendar-change="searchitem.calendarChange"
            @ok="searchitem.changeSubmit?onSubmit():null"
            @change="searchitem.changeSubmit?onSubmit():null"
          />
        </a-config-provider>
        <slot v-else-if="searchitem.type==='slot'" :name="searchitem.slotName" :data="searchFormData[searchitem.prop]" :item="searchitem" />
      </el-form-item>
      <div class="d-common-flex-row">
        <slot name="searchbutton-prepend" />
        <template v-for="searchbutton in searchButtons" :key="searchbutton">
          <el-button v-if="searchbutton.type==='search'" v-blur type="primary" :disabled="showLoading" @click="onSubmit()">
            <d-icon class="el-icon el-icon--left" :icon-config="searchIcon" />
            搜索
          </el-button>
          <el-button v-if="searchbutton.type==='clear'" v-blur :disabled="showLoading" @click="onClear">
            <d-icon class="el-icon el-icon--left" :icon-config="clearIcon" />
            重置
          </el-button>
          <el-form
            v-else-if="searchbutton.type==='inputsearch'"
            ref="inputSearchRef"
            class="d-header-form"
            :rules="inputSearchRule"
            :model="searchbutton"
            :label-width="0"
            :style="getInputsearchStyle(searchbutton.width)"
            @submit.prevent
          >
            <el-form-item prop="value">
              <el-input
                v-model="searchbutton.value"
                v-el-focus="searchbutton.autofocus"
                class="d-common-height-line"
                clearable
                :placeholder="searchbutton.placeholder"
                @keyup.enter="onSubmit(searchbutton.value)"
                @clear="onSubmit(searchbutton.value)"
              >
                <template #append>
                  <el-button v-blur class="d-header-search-button" type="primary" :disabled="showLoading" @click="onSubmit(searchbutton.value)">
                    <d-icon :icon-config="{icon:'Search',type:'el'}" />
                  </el-button>
                </template>
              </el-input>
            </el-form-item>
          </el-form>
        </template>
        <slot name="searchbutton-append" />
      </div>
    </el-form>
  </div>
  <div v-if="relativePosition==='bt'" class="d-table-header-buttons d-common-flex-row d-common-flex-waper d-common-width-full">
    <slot name="operbutton-prepend" />
    <template v-for="operbutton in operButtons" :key="operbutton.code">
      <template v-if="getButtonShow(operbutton)">
        <el-button
          v-if="operbutton.type==='noraml'||operbutton.type==='icon'"
          v-blur
          :type="operbutton.elType?operbutton.elType:'primary'"
          :plain="operbutton.plain"
          :style="operbutton.style"
          :disabled="operbutton.disabled"
          :class="operbutton.class"
          :loading="showLoading"
          @click="onOperation(operbutton.code)"
        >
          <d-icon v-if="operbutton.iconConfig" class="el-icon el-icon--left" :icon-config="operbutton.iconConfig" />
          {{ operbutton.type==='icon'?'':getButtonLabel(operbutton) }}
        </el-button>
        <el-button
          v-else-if="operbutton.type==='link'"
          v-blur
          type="primary"
          link
          :disabled="operbutton.disabled"
          :style="operbutton.style"
          :class="operbutton.class"
          :loading="showLoading"
          @click="onOperation(operbutton.code)"
        >
          {{ getButtonLabel(operbutton) }}
        </el-button>
      </template>
    </template>
    <slot name="operbutton-append" />
  </div>
</template>

<style scoped>
.d-table-header__wapper{
  height: auto;
  --from-padding:var(--d-padding-level-1)
}
.d-table-from-con{
  /* padding-left: var(--from-padding); */
  padding-right: calc(var(--from-padding) * 2);
  column-gap: 16px;
  row-gap: 18px;
  margin-bottom: 22px;
}
.d-table-header-buttons{
  margin-bottom: calc(var(--d-margin-level-2) + 1px);
}
.d-table-header-buttons:empty{
  margin-bottom: 0;
}
.d-header-more{
  margin-left: var(--d-margin-level-2);
}
</style>